import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { bs58 } from "@project-serum/anchor/dist/cjs/utils/bytes";
import { decode } from "@project-serum/anchor/dist/cjs/utils/bytes/hex";
import { PublicKey, SystemProgram, SYSVAR_SLOT_HASHES_PUBKEY, Transaction, LAMPORTS_PER_SOL, SimulateTransactionConfig } from "@solana/web3.js"
import { BN } from "bn.js";
import { SolanaHashbet } from "../target/types/solana_hashbet";

describe("solana-hashbet", () => {
  // Configure the client to use the local cluster.
  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);

  const program = anchor.workspace.SolanaHashbet as Program<SolanaHashbet>;

  it("sys_recharge", async () => {
    return;
    const [bet_pool] = await PublicKey.findProgramAddress(
      [Buffer.from(anchor.utils.bytes.utf8.encode("bet_pool_seed"))],
      program.programId
    );
    const tx = await program.methods
      .sysRecharge(new BN(100 * 10 ** 9))
      .accounts({
        authority: provider.wallet.publicKey,
        betPool: bet_pool,
        systemProgram: SystemProgram.programId
      })
      .rpc();
    console.log("Your transaction signature", tx);
  });

  it("hash_bet", async () => {
    return;
    const [bet_pool] = await PublicKey.findProgramAddress(
      [Buffer.from(anchor.utils.bytes.utf8.encode("bet_pool_seed"))],
      program.programId
    );
    //3qhDtNjGm2PpNZJCXG923p6A7RJ9eofLrixY5tcDARX3
    let tx = await program.methods
      .hashBet(new BN(2 * 10 ** 9))
      .accounts({
        payer: provider.wallet.publicKey,
        betPool: bet_pool,
        slotHashes: SYSVAR_SLOT_HASHES_PUBKEY,
        systemProgram: SystemProgram.programId
      }).rpc();
    console.log("Your transaction signature", tx);
  });

  it("sys_withdrawal", async () => {
    return;
    const [bet_pool] = await PublicKey.findProgramAddress(
      [Buffer.from(anchor.utils.bytes.utf8.encode("bet_pool_seed"))],
      program.programId
    );
    const tx = await program.methods
      .sysWithdrawal(new BN(20 * 10 ** 9))
      .accounts({
        authority: provider.wallet.publicKey,
        betPool: bet_pool,
        systemProgram: SystemProgram.programId
      })
      .rpc();
    console.log("Your transaction signature", tx);
  });

  it("test", async () => {

    let from = provider.wallet.publicKey;
    let to = new PublicKey("CzD67wGUf7TFFmekeAbjFM1HyomXik7jMVCTGhpVAgzJ");

    const transaction = new Transaction().add(
      SystemProgram.transfer({
        fromPubkey: from,
        toPubkey: to,
        lamports: LAMPORTS_PER_SOL / 100,
      })
    );
    transaction.recentBlockhash = (await provider.connection.getLatestBlockhash("max")).blockhash;
    transaction.feePayer = provider.wallet.publicKey;

    let msg = transaction.serializeMessage();
    // console.log(msg);
    let newmsg = anchor.web3.VersionedMessage.deserialize(msg);
    // console.log(newmsg);
    // let fee = await provider.connection.getFeeForMessage(newmsg);
    // console.log(fee);
    let vt = new anchor.web3.VersionedTransaction(newmsg);
    let simu = await provider.connection.simulateTransaction(vt, {
      sigVerify: false,
      accounts: {
        encoding: 'base64',
        addresses: [
          from.toBase58(),
          to.toBase58()
        ]
      }
    });
    console.log("accounts", simu.value.accounts);
    console.log("balance change :");
    console.log(from.toBase58(), simu.value.accounts[0].lamports - await provider.connection.getBalance(from));
    console.log(to.toBase58(), simu.value.accounts[1].lamports - await provider.connection.getBalance(to));
    let networkFee = await transaction.getEstimatedFee(provider.connection);
    console.log("networkFee", networkFee);
  });
});

// const transaction = new Transaction().add(
//   new TransactionInstruction({
//     keys: [
//       {pubkey: signer.publicKey, isSigner: true, isWritable: false},
//       {pubkey: programDerivedAddress, isSigner: false, isWritable: true},
//       {pubkey: toAddress, isSigner: false, isWritable: true},
//       {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}
//     ],
//     data: Buffer.from(new Uint8Array([])),
//     programId: programId,
//   })
// );

// await sendAndConfirmTransaction(
//     connection,
//     transaction,
//     [signer],
// );